/* 
 * File:   TestUnitDeck.cpp
 * Author: Pouja Nikray
 *
 * Created on 12-aug-2012, 0:42:14
 */

#include <stdlib.h>
#include <iostream>
#include "../Duel.h"
#include "../MonsterCard.h"
#include "../Deck.h"
/*
 * Simple C++ Test Suite
 */

Deck* createDeck(){
    Deck* deck=new Deck();
    
    MonsterCard *mc1 = new MonsterCard("Black Dragon", "SY-50", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    MonsterCard *mc2 = new MonsterCard("White Dragon", "SY-60", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");    
    MonsterCard *mc3 = new MonsterCard("Blue Dragon", "SY-70", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");  
    
    deck->addCard(mc1);
    deck->addCard(mc2);
    deck->addCard(mc3);
    
    return deck;
}

void testAddCard() {
<<<<<<< .mine
    MonsterCard *mc1 = new MonsterCard("Black Dragon", "SY-50", "Pwnage!", "Dark", 5, 2000, 1900, "Beasty Dragon");
    Deck* deck=new Deck();
    deck->addCard(mc1);
    if (deck->size()!=1 /*check result*/) {
        std::cout << "%TEST_FAILED% time=0 testname=testAddCard (TestUnitDeck) message=should be 1 but it is "<<deck->size() << std::endl;
=======
    MonsterCard *mc1 = new MonsterCard("Black Dragon", "SY-50", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    Deck* deck=new Deck();
    deck->addCard(mc1);
    if (deck->size()!=1 /*check result*/) {
        std::cout << "%TEST_FAILED% time=0 testname=testAddCard (TestUnitDeck) message=should be 1 but it is "<<deck->size() << std::endl;
>>>>>>> .r45
    }
    delete mc1;
}

void testFind() {
    MonsterCard *mc1 = new MonsterCard("Black Dragon", "SY-50", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    Deck* deck=createDeck();
    list<Card*>::iterator result = deck->find(mc1);
    if (result==NULL){
        std::cout << "%TEST_FAILED% time=0 testname=testFind (TestUnitDeck) message=no card found" << std::endl;
    }
    else if ((*result)->getNumber()!="SY-50") {
        
        std::cout << "%TEST_FAILED% time=0 testname=testFind (TestUnitDeck) message=found wrong card should be SY-50 but was " 
                <<(*result)->getNumber()
                << std::endl;
    }
    delete deck;
    delete mc1;
}

void testRemoveCard() {
    Deck* deck=createDeck();
    MonsterCard *mc2 = new MonsterCard("White Dragon", "SY-60", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon"); 
    
    deck->addCard(mc2);
    
    if (deck->size()!=4){
        std::cout << "%TEST_FAILED% time=0 testname=testRemoveCard (TestUnitDeck) message=there should be 4 cards but there are "
                << deck->size() << " cards"
                << std::endl;
    }
    
    deck->removeCard(mc2);
    
    if (deck->size()!=3){
        std::cout << "%TEST_FAILED% time=0 testname=testRemoveCard (TestUnitDeck) message=there should be 3 cards but there are "
                << deck->size() << " cards"
                << std::endl;
    }
    
    delete deck;
}

void testDrawCard(){
    Deck* deck=createDeck();
    Card* card=deck->drawCard();
    if (card->getNumber()!="SY-70"){
        std::cout << "%TEST_FAILED% time=0 testname=testDrawCard (TestUnitDeck) message=the first drawn card should be SY-70 it is "
                << card->getNumber()
                << std::endl;
    }
    delete deck;
}

void testEqualTrue(){
    Deck* deck=createDeck();
    Deck* other=createDeck();
    if(*deck!=(*other)){
        std::cout << "%TEST_FAILED% time=0 testname=testEqualTrue (TestUnitDeck) message=both decks should equal but they aren't" << std::endl;
    }    
    delete deck;
    delete other;
}

void testEqualFalse(){
    Deck* deck=createDeck();
    Deck* other=new Deck();
    
    MonsterCard *mc1 = new MonsterCard("Black Dragon", "SY-50", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    MonsterCard *mc2 = new MonsterCard("White Dragon", "SY-60", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    MonsterCard *mc3 = new MonsterCard("Blue Dragon", "SY-70", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon");
    MonsterCard *mc3diff = new MonsterCard("Blue Dragon", "SY-80", "Pwnage!", MonsterCard::DARK, 5, 2000, 1900, "Beasty Dragon"); 
    
    other->addCard(mc1);
    other->addCard(mc2);
    
    if(*deck==(*other)){
        std::cout << "%TEST_FAILED% time=0 testname=testEqualFalse (TestUnitDeck) message=size differ so it should return false" << std::endl;
    }
    
    other->addCard(mc3diff);
    
    if(*deck==(*other)){
        std::cout << "%TEST_FAILED% time=0 testname=testEqualFalse (TestUnitDeck) message=last card differs so it should return false" << std::endl;
    }
    
    other=new Deck();
    other->addCard(mc2);
    other->addCard(mc1);
    other->addCard(mc3);
    
    if(*deck==(*other)){
        std::cout << "%TEST_FAILED% time=0 testname=testEqualFalse (TestUnitDeck) message=order differs so it should return false" << std::endl;
    }
    delete deck;
    delete other;
    delete mc1;
    delete mc2;
    delete mc3;
    delete mc3diff;
}

void testShuffle() {
    Deck* deck=createDeck();
    deck->shuffle();
    Deck* unshuffledDeck=createDeck();
    if (*deck==(*unshuffledDeck)) {
        std::cout << "%TEST_FAILED% time=0 testname=testShuffle (TestUnitDeck) message=two decks should differ in order" << std::endl;
    }
    delete deck;
    delete unshuffledDeck;
}

void testFindN(){
    Deck* deck=createDeck();
    Card* mc1=deck->findN(2);
    Card* mc3=deck->findN(0);
    if (mc3->getNumber()!="SY-70"){
        std::cout << "%TEST_FAILED% time=0 testname=testFindN (TestUnitDeck) message=card on position 0 should be SY-70 but it is "
                << mc1->getNumber()
                << std::endl;
    }
    if (mc1->getNumber()!="SY-50"){
        std::cout << "%TEST_FAILED% time=0 testname=testFindN (TestUnitDeck) message=card on position 2 should be SY-50 but it is "
                << mc1->getNumber()
                << std::endl;
    }   
    delete deck;
}

void testSize() {
    Deck* deck=createDeck();
    int result = deck->size();
    if (result!=3) {
        std::cout << "%TEST_FAILED% time=0 testname=testSize (TestUnitDeck) message=size should be 3 but it is "<<deck->size() << std::endl;
    }
    delete deck;
}

int main(int argc, char** argv) {
    std::cout << "%SUITE_STARTING% TestUnitDeck" << std::endl;
    std::cout << "%SUITE_STARTED%" << std::endl;

    std::cout << "%TEST_STARTED% testAddCard (TestUnitDeck)" << std::endl;
    testAddCard();
    std::cout << "%TEST_FINISHED% time=0 testAddCard (TestUnitDeck)" << std::endl;

    std::cout << "%TEST_STARTED% testEqualFalse (TestUnitDeck)" << std::endl;
    testEqualFalse();
    std::cout << "%TEST_FINISHED% time=0 testEqualFalse (TestUnitDeck)" << std::endl;
    
    std::cout << "%TEST_STARTED% testEqualTrue (TestUnitDeck)" << std::endl;
    testEqualTrue();
    std::cout << "%TEST_FINISHED% time=0 testEqualTrue (TestUnitDeck)" << std::endl;
    
    std::cout << "%TEST_STARTED% testFind (TestUnitDeck)" << std::endl;
    testFind();
    std::cout << "%TEST_FINISHED% time=0 testFind (TestUnitDeck)" << std::endl;

    std::cout << "%TEST_STARTED% testDrawCard (TestUnitDeck)" << std::endl;
    testDrawCard();
    std::cout << "%TEST_FINISHED% time=0 testDrawCard (TestUnitDeck)" << std::endl;
    
    std::cout << "%TEST_STARTED% testFindN (TestUnitDeck)" << std::endl;
    testFindN();
    std::cout << "%TEST_FINISHED% time=0 testFindN (TestUnitDeck)" << std::endl;
    
    std::cout << "%TEST_STARTED% testRemoveCard (TestUnitDeck)" << std::endl;
    testRemoveCard();
    std::cout << "%TEST_FINISHED% time=0 testRemoveCard (TestUnitDeck)" << std::endl;

    std::cout << "%TEST_STARTED% testShuffle (TestUnitDeck)" << std::endl;
    testShuffle();
    std::cout << "%TEST_FINISHED% time=0 testShuffle (TestUnitDeck)" << std::endl;

    std::cout << "%TEST_STARTED% testSize (TestUnitDeck)" << std::endl;
    testSize();
    std::cout << "%TEST_FINISHED% time=0 testSize (TestUnitDeck)" << std::endl;

    std::cout << "%SUITE_FINISHED% time=0" << std::endl;

    return (EXIT_SUCCESS);
}

